package Service.SurroundService;

import Factory.ParamChangeUtil;
import Model.SurroundModel.Ship;
import Model.SurroundModel.Target;
import Service.ShipCalculate;

import java.util.ArrayList;
import java.util.List;

public class FirstOrderAdaptStaticTargetsService extends ShipCalculate {

    ParamChangeUtil paramChangeUtil = new ParamChangeUtil(); // 数据转换器

    public static String name = "一阶动态包围组件";

    static int SleepTime; // 计算休眠间隔
    static volatile boolean isWorking = false; // 是否运行

    // 计算实例，包含计算信息
    public Target target; // 目标队列
    public Ship ship; // 船队

    /**
     * 转换示例
     *
     * @param sleepTime 睡眠时间
     */
    public FirstOrderAdaptStaticTargetsService(int sleepTime) {
        this.SleepTime = sleepTime;
        this.isWorking = true;
    }

    public void Init() {
        System.out.println(GetName() + "初始化了");
        this.initTarget();
        this.initShip();

        // 保存数据
        saveData(0);
    }

    public void Calculate() {
        this.calculate();
    }

    public boolean GetWorkingState() {
        return this.isWorking;
    }

    public void ShutDown() {
        this.isWorking = false;
    }

    public String GetName() {
        return name;
    }

    public void SetCalSpeed(int sleepTime){ this.SleepTime = sleepTime;};

    // 初始化目标信息
    public void initTarget() {
        target = new Target();
        target.initCircularPosition();
        target.setCenter();
    }

    // 初始化智能体
    public void initShip() {

        ship = new Ship();

        //初始化智能体
        List<Ship> shipList = new ArrayList<>();
        shipList.add(new Ship(1, -5, 9));
        shipList.add(new Ship(2, 3, 4));
        shipList.add(new Ship(3, 7, 6));
        shipList.add(new Ship(4, 9, 4));
        ship.setPosition(shipList);

        //不断调整初始P值使得各个智能体对于目标估计中心位置初始值相同
        for (int i = 0; i < 50000; i++) {
            ship.setφ(0.00002);
            ship.setP(0.00002,target);
        }
    }

    /**
     * 保存数据
     *
     * @param time 时间
     */
    public void saveData(double time) {
        //保存目标队列当前位置
        paramChangeUtil.SaveAllData(this, time);
    }

    // 计算并更新需要更新的数据
    public void calculate() {

        isWorking = true;

        double timeLength = 0.001;
        double saveTime = 0;            //保存时间
        while (!ship.formationFinish(timeLength, target) && isWorking) {

            try {
                Thread.sleep(SleepTime);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //通过控制器去修改智能体对于目标的各项数值
            ship.formationController(timeLength, target);

            // 保存数据
            saveData(saveTime);

            //时间跳到下一时刻
            saveTime++;
        }

        isWorking = false;
    }

}
